import matplotlib.pyplot as plt
import math
import pandas as pd
from matplotlib.pyplot import MultipleLocator
import matplotlib.ticker as ticker
import sys
import numpy as np
sys.path.append(".")
legend_font = {'family': 'Arial',
               'weight': 'normal',
               'size': 18,
               }

label_font = {'family': "Arial",
              'weight': 'normal',
              'size': 18,
              }

tick_font = {'family': 'Arial',
             'weight': 'normal',
             'size': 18
             }
marker_size = 1
line_width = 2

color_a = 'whitesmoke'
color_b = 'lightgrey'
color_c = 'darkgrey'
color_d = 'dimgrey'
color_e = 'black'

color_a1 = 'bisque'
color_b1 = 'wheat'
color_c1 = 'goldenrod'
color_d1 = 'orange'
color_e1 = 'darkorange'

color_a2 = 'rosybrown'
color_b2 = 'lightcoral'
color_c2 = 'tomato'
color_d2 = "firebrick"#''""
color_e2 = 'darkred'

color_a3 = 'lightgreen'
color_b3 = 'forestgreen'
color_c3 = 'limegreen'
color_d3 = "darkgreen"#''""
#color_e3 = 'darkred'


err_bar_kw = dict(ecolor="red", elinewidth=3, lw=5, capsize=5, capthick=2)

SLA=0.221
def plot_gpu_partition_latency_hybrid():
    def bar_color(model_name):
        result = None
        if model_name == "IA":
            result = [color_a,color_b,color_c,color_d]
        elif model_name == "IB":
            result = [color_a1, color_b1, color_c1, color_d1]
        elif model_name == "RA":
            result = [color_a2, color_b2, color_c2, color_d2]
        else:
            result = [color_a3, color_b3, color_c3, color_d3]
        return result

    fig, ax = plt.subplots(sharex="col")
    model_name = "hybrid"
    excel = "./data/" + model_name + ".xlsx"

    # the shortest model runs first without batch.
    data_seq = pd.read_excel(excel, index_col=0, sheet_name="seq")
    data_batch = pd.read_excel(excel, index_col=0, sheet_name="batch")
    A_seq = data_seq.loc[1, :]
    B_seq = data_seq.loc[2, :]
    C_seq = data_seq.loc[3, :]
    D_seq = data_seq.loc[4, :]

    A_batch = data_batch.loc[1, :]
    B_batch = data_batch.loc[2, :]
    C_batch = data_batch.loc[3, :]
    D_batch = data_batch.loc[4, :]

    # 1. read all the latency ratio
    # ax = fig.add_subplot(111)
    fig.set_size_inches(8, 6)
    width = 0.03
    x = np.array([0, 0.15])

    color = bar_color(A_seq["name"])
    ax.bar(x[0] - 1.5*width, A_seq["mobile"], width, color=color[0], edgecolor="k", label=" RA mobile")
    ax.bar(x[0] - 1.5*width, A_seq["network"], width, color=color[1], bottom=A_seq["mobile"], edgecolor="k",
           label="RA network")
    ax.bar(x[0] - 1.5*width, A_seq["queue"], width, color=color[2], edgecolor="k",
           bottom=A_seq["network"] + A_seq["mobile"], label="RA queue")
    ax.bar(x[0] - 1.5*width, A_seq["edge"], width, color=color[3], edgecolor="k",
           bottom=A_seq["network"] + A_seq["mobile"] + A_seq["queue"], label="RA edge")

    color = bar_color(B_seq["name"])
    ax.bar(x[0] - width / 2, B_seq["mobile"], width, color=color[0], edgecolor="k", label=" IA mobile")
    ax.bar(x[0] - width / 2, B_seq["network"], width, color=color[1], bottom=B_seq["mobile"], edgecolor="k", label=" IA network")
    ax.bar(x[0] - width / 2, B_seq["queue"], width, color=color[2], edgecolor="k",
           bottom=B_seq["network"] + B_seq["mobile"], label=" IA queue")
    ax.bar(x[0] - width / 2, B_seq["edge"], width, color=color[3], edgecolor="k",
           bottom=B_seq["network"] + B_seq["mobile"] + B_seq["queue"], label=" IA edge")

    color = bar_color(C_seq["name"])
    ax.bar(x[0] + width / 2, C_seq["mobile"], width, color=color[0], edgecolor="k",label="RB mobile")
    ax.bar(x[0] + width / 2, C_seq["network"], width, color=color[1], bottom=C_seq["mobile"], edgecolor="k",label="RB network")
    ax.bar(x[0] + width / 2, C_seq["queue"], width, color=color[2], edgecolor="k",
           bottom=C_seq["network"] + C_seq["mobile"],label="RB queue")
    ax.bar(x[0] + width / 2, C_seq["edge"], width, color=color[3], edgecolor="k",
           bottom=C_seq["network"] + C_seq["mobile"] + C_seq["queue"],label="RB edge")

    color = bar_color(D_seq["name"])
    ax.bar(x[0] + 1.5*width, D_seq["mobile"], width, color=color[0], edgecolor="k", label="IB mobile")
    ax.bar(x[0] + 1.5*width, D_seq["network"], width, color=color[1], bottom=D_seq["mobile"], edgecolor="k",
           label="IB network")
    ax.bar(x[0] + 1.5*width, D_seq["queue"], width, color=color[2], edgecolor="k",
           bottom=D_seq["network"] + D_seq["mobile"], label="IB queue")
    ax.bar(x[0] + 1.5*width, D_seq["edge"], width, color=color[3], edgecolor="k",
           bottom=D_seq["network"] + D_seq["mobile"] + D_seq["queue"], label="IB edge")

    color = bar_color(A_batch["name"])
    ax.bar(x[1] - 1.5*width, A_batch["mobile"], width, color=color[0], edgecolor="k")
    ax.bar(x[1] - 1.5*width, A_batch["network"], width, color=color[1], bottom=A_batch["mobile"], edgecolor="k")
    ax.bar(x[1] - 1.5*width, A_batch["queue"], width, color=color[2], edgecolor="k",
           bottom=A_batch["network"] + A_batch["mobile"])
    ax.bar(x[1] - 1.5*width, A_batch["edge"], width, color=color[3], edgecolor="k",
           bottom=A_batch["network"] + A_batch["mobile"] + A_batch["queue"])

    color = bar_color(B_batch["name"])
    ax.bar(x[1] - width / 2, B_batch["mobile"], width, color=color[0], edgecolor="k")
    ax.bar(x[1] - width / 2, B_batch["network"], width, color=color[1], bottom=B_batch["mobile"], edgecolor="k")
    ax.bar(x[1] - width / 2, B_batch["queue"], width, color=color[2], edgecolor="k",
           bottom=B_batch["network"] + B_batch["mobile"])
    ax.bar(x[1] - width / 2, B_batch["edge"], width, color=color[3], edgecolor="k",
           bottom=B_batch["network"] + B_batch["mobile"] + B_batch["queue"])

    color = bar_color(C_batch["name"])
    ax.bar(x[1] + width / 2, C_batch["mobile"], width, color=color[0], edgecolor="k")
    ax.bar(x[1] + width / 2, C_batch["network"], width, color=color[1], bottom=C_batch["mobile"], edgecolor="k")
    ax.bar(x[1] + width / 2, C_batch["queue"], width, color=color[2], edgecolor="k",
           bottom=C_batch["network"] + C_batch["mobile"])
    ax.bar(x[1] + width / 2, C_batch["edge"], width, color=color[3], edgecolor="k",
           bottom=C_batch["network"] + C_batch["mobile"] + C_batch["queue"])

    color = bar_color(D_batch["name"])
    ax.bar(x[1] + 1.5*width, D_batch["mobile"], width, color=color[0], edgecolor="k")
    ax.bar(x[1] + 1.5*width, D_batch["network"], width, color=color[1], bottom=D_batch["mobile"], edgecolor="k")
    ax.bar(x[1] + 1.5*width, D_batch["queue"], width, color=color[2], edgecolor="k",
           bottom=D_batch["network"] + D_batch["mobile"])
    ax.bar(x[1] + 1.5*width, D_batch["edge"], width, color=color[3], edgecolor="k",
           bottom=D_batch["network"] + D_batch["mobile"] + D_batch["queue"])

    ax.set_xticks([x[0]-1.5*width,x[0]-width/2,x[0]+width/2,x[0]+1.5*width,x[1]-1.5*width,x[1]-width/2,x[1]+width/2,x[1]+1.5*width])
    name_list = list(data_seq["name"].values)
    temp = list(data_batch["name"].values)
    name_list.extend(temp)

    ax.set_xticklabels(name_list, tick_font)
    #ax.set_xlabel(model_name, label_font)
    ax.grid(linestyle="-.")
    ax.yaxis.set_major_locator(MultipleLocator(0.04))
    ax.tick_params(axis='y', labelsize=tick_font["size"])
    ax.set_ylim(0, 0.13)
    # ax.set_ylim(0,0.08)
    ax.set_ylabel("Latency (S)", label_font)
    ax.text(x[0], 0.113, 'seq',size=22,color="red", ha='center', va='bottom')
    ax.text(x[1], 0.113, 'batch',size=22,color="red", ha='center', va='bottom')

    fig.legend(prop=legend_font, loc="upper center", framealpha=0.1, ncol=4,columnspacing=0.1)  # ,columnspacing=0.1
    fig.tight_layout()
    fig.subplots_adjust(top=0.7)
    # plt.savefig("../image/bg_resource_allocation_fig3c.pdf", bbox_inches='tight', pad_inches=0)
    plt.show()
def plot_gpu_partition_latency():
    fig, ax = plt.subplots(sharex="col")
    model_name = "inception"
    excel = "./data/"+model_name+".xlsx"

    # the shortest model runs first without batch.
    data_seq = pd.read_excel(excel, index_col=0,sheet_name="seq")
    data_batch = pd.read_excel(excel, index_col=0,sheet_name="batch")
    A_seq = data_seq.loc[model_name+"_A",:]
    B_seq = data_seq.loc[model_name+"_B", :]
    A_batch = data_batch.loc[model_name+"_A", :]
    B_batch = data_batch.loc[model_name+"_B", :]

    # 1. read all the latency ratio
    # ax = fig.add_subplot(111)
    fig.set_size_inches(6, 4)
    width = 0.05
    x = np.array([0, 0.15])

    ax.bar(x[0]-width/2, A_seq["mobile"], width, color=color_a,edgecolor="k",label="mobile")
    ax.bar(x[0]-width/2, A_seq["network"], width, color=color_b,bottom=A_seq["mobile"],edgecolor="k",label="network")
    ax.bar(x[0]-width/2, A_seq["queue"], width, color=color_c,edgecolor="k",
           bottom=A_seq["network"]+A_seq["mobile"],label="queue")

    ax.bar(x[0]-width/2, A_seq["edge"], width, color=color_d,edgecolor="k",
           bottom=A_seq["network"]+A_seq["mobile"]+A_seq["queue"],label="edge")
    ax.text(x[0]-width/2, A_seq["network"]+A_seq["mobile"]
            +A_seq["queue"]+A_seq["edge"], 'seq',tick_font, ha='center', va='bottom')

    ax.bar(x[0]+width/2, A_batch["mobile"], width, color=color_a,edgecolor="k")
    ax.bar(x[0]+width/2, A_batch["network"], width, color=color_b,bottom=A_batch["mobile"],edgecolor="k")
    ax.bar(x[0]+width/2, A_batch["queue"], width, color=color_c,edgecolor="k",
           bottom=A_batch["network"]+A_batch["mobile"])

    ax.bar(x[0]+width/2, A_batch["edge"], width, color=color_d,edgecolor="k",
           bottom=A_batch["network"]+A_batch["mobile"]+A_batch["queue"])
    ax.text(x[0]+width/2, A_batch["network"]+A_batch["mobile"]
            +A_batch["queue"]+A_batch["edge"], 'batch',tick_font, ha='center', va='bottom')

    ax.bar(x[1]-width/2, B_seq["mobile"], width, color=color_a1,edgecolor="k",label="mobile")
    ax.bar(x[1]-width/2, B_seq["network"], width, color=color_b1,bottom=B_seq["mobile"],edgecolor="k",label="network")
    ax.bar(x[1]-width/2, B_seq["queue"], width, color=color_c1,edgecolor="k",
           bottom=B_seq["network"]+B_seq["mobile"],label="queue")
    ax.bar(x[1]-width/2, B_seq["edge"], width, color=color_d1,edgecolor="k",
           bottom=B_seq["network"]+B_seq["mobile"]+B_seq["queue"],label="edge")
    ax.text(x[1]-width/2, B_seq["network"]+B_seq["mobile"]
            +B_seq["queue"]+B_seq["edge"], 'seq',tick_font, ha='center', va='bottom')

    ax.bar(x[1]+width/2, B_batch["mobile"], width, color=color_a1,edgecolor="k")
    ax.bar(x[1]+width/2, B_batch["network"], width, color=color_b1,bottom=B_batch["mobile"],edgecolor="k")
    ax.bar(x[1]+width/2, B_batch["queue"], width, color=color_c1,edgecolor="k",
           bottom=B_batch["network"]+B_batch["mobile"])

    ax.bar(x[1]+width/2, B_batch["edge"], width, color=color_d1,edgecolor="k",
           bottom=B_batch["network"]+B_batch["mobile"]+B_batch["queue"])
    ax.text(x[1]+width/2, B_batch["network"]+B_batch["mobile"]
            +B_batch["queue"]+B_batch["edge"], 'batch',tick_font, ha='center', va='bottom')
    ax.set_xticks(x)
    ax.set_xticklabels(["#layer:16\n"+"(bw="+str(A_batch["bw"])+"Mbps)", "#layer:0\n"+"(bw="+str(B_batch["bw"])+"Mbps)"], tick_font)
    ax.set_xlabel(model_name,label_font)
    ax.grid(linestyle="-.")
    ax.yaxis.set_major_locator(MultipleLocator(0.04))
    ax.tick_params(axis='y', labelsize=tick_font["size"])
    ax.set_ylim(0,0.13)
    #ax.set_ylim(0,0.08)
    ax.set_ylabel("Latency (S)", label_font)

    fig.legend(prop=legend_font, loc="upper center", framealpha=0.1, ncol=3)#,columnspacing=0.1
    fig.tight_layout()
    fig.subplots_adjust(top=0.7)
    #plt.savefig("../image/bg_resource_allocation_fig3c.pdf", bbox_inches='tight', pad_inches=0)
    plt.show()

def plot_gpu_partition_throughput():
    fig, ax = plt.subplots()
    model_name = "inception"
    fig.set_size_inches(6, 4)
    width = 0.03
    x = np.array([0, 0.1,0.2])


    ax.bar(x[0] - width/2, 117, width, color=color_b,edgecolor="k")
    ax.text(x[0] - width , 117, "seq", tick_font)

    ax.bar(x[0] + width / 2, 125, width, color=color_b,edgecolor="k")
    ax.text(x[0] , 125, "batch", tick_font)

    ax.bar(x[1] - width/2,181, width, color=color_b1,edgecolor="k")
    ax.text(x[1] - width , 181, "seq", tick_font)

    ax.bar(x[1]+ width / 2, 200, width, color=color_b1,edgecolor="k")
    ax.text(x[1] , 200, "batch", tick_font)

    ax.bar(x[2]-width/2, 142, width, color=color_b2,edgecolor="k")
    ax.text(x[2] - width, 142, "seq", tick_font)

    ax.bar(x[2]+ width / 2, 153, width, color=color_b2,edgecolor="k")
    ax.text(x[2] , 153, "batch", tick_font)

    ax.set_xticks(x)
    ax.set_xticklabels(["Inception", "ResNet","Hybrid"], tick_font)
    ax.grid(linestyle="-.")
    ax.yaxis.set_major_locator(MultipleLocator(40))
    ax.tick_params(axis='y', labelsize=tick_font["size"])
    ax.set_ylabel("Throughput (RPS)", label_font)
    fig.tight_layout()
    #plt.savefig("../image/bg_resource_allocation_fig3c.pdf", bbox_inches='tight', pad_inches=0)
    plt.show()
#plot_gpu_partition_latency()
#plot_gpu_partition_latency_hybrid()
plot_gpu_partition_throughput()